package net.xcrane.xmpp.tools.ui;

import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.net.InetAddress;
import java.util.Collection;
import java.util.Date;
import java.util.List;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JScrollBar;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.ScrollPaneConstants;
import javax.swing.SwingUtilities;

import org.jivesoftware.smack.SmackException.NotConnectedException;
import org.jivesoftware.smack.StanzaListener;
import org.jivesoftware.smack.packet.ExtensionElement;
import org.jivesoftware.smack.packet.IQ;
import org.jivesoftware.smack.packet.Message;
import org.jivesoftware.smack.packet.Presence;
import org.jivesoftware.smack.packet.Stanza;
import org.jivesoftware.smack.packet.XMPPError;
import org.jivesoftware.smack.roster.Roster;
import org.jivesoftware.smack.roster.RosterEntry;
import org.jivesoftware.smack.roster.RosterListener;
import org.jivesoftware.smack.sasl.SASLMechanism;
import org.jivesoftware.smack.tcp.XMPPTCPConnection;
import org.jivesoftware.smack.tcp.XMPPTCPConnectionConfiguration;
import org.jivesoftware.smackx.jiveproperties.packet.JivePropertiesExtension;
import org.jivesoftware.smackx.muc.MultiUserChat;
import org.jivesoftware.smackx.muc.MultiUserChatManager;
import org.jivesoftware.smackx.ping.packet.Ping;
import org.jivesoftware.smackx.snyc.packet.Fin;
import org.jivesoftware.smackx.snyc.packet.OMAmount;
import org.jivesoftware.smackx.snyc.packet.OfflineMessageItems;
import org.jivesoftware.smackx.snyc.packet.OfflineMsgAmount;
import org.jivesoftware.smackx.snyc.packet.OfflineMsgPage;
import org.jivesoftware.smackx.snyc.packet.RevOfflineMsgPage;
import org.jivesoftware.smackx.snyc.packet.Sync;
import org.jivesoftware.smackx.snyc.packet.ThanksgivingElment;
import org.jxmpp.jid.EntityBareJid;
import org.jxmpp.jid.Jid;
import org.jxmpp.jid.impl.JidCreate;
import org.jxmpp.jid.parts.Resourcepart;
import org.jxmpp.stringprep.XmppStringprepException;


public class SmackFrameXimen {

	private JFrame frmXmppTools;
	private JTextField txtName;
	private JTextField txtPwd;
	private JTextField txtHost;
	private JTextField txtPort;

	private JTextArea txtMsg = null;
	private JTextArea txtChat = null;
	
	private XMPPTCPConnection xmppCnn = null;
	
	private Roster roster;
	
	private JTextField txtTo;
	private JTextField txtStatus;
	
	private JScrollPane spMsg = null;
	
	private JTextField txtDomain;	
	private JTextField txtGroup;
	
	
	
	/**
	 * Launch the application.
	 */
	public static void main(String[] args) {
		EventQueue.invokeLater(new Runnable() {
			public void run() {
				try {
					SmackFrameXimen window = new SmackFrameXimen();
					window.frmXmppTools.setVisible(true);
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		});
	}

	/**
	 * Create the application.
	 */
	public SmackFrameXimen() {
		initialize();
	}

	/**
	 * Initialize the contents of the frame.
	 */
	private void initialize() {		
		frmXmppTools = new JFrame();
		frmXmppTools.setTitle("XMPP Tools");
		frmXmppTools.setBounds(700, 300, 953, 624);
		frmXmppTools.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		frmXmppTools.getContentPane().setLayout(null);
		
		JLabel lblName = new JLabel("Name:");
		lblName.setBounds(40, 38, 86, 30);
		frmXmppTools.getContentPane().add(lblName);
		
		txtName = new JTextField();
		txtName.setText("ximen");
		txtName.setBounds(140, 38, 155, 30);
		frmXmppTools.getContentPane().add(txtName);
		txtName.setColumns(10);
		
		JLabel labelPwd = new JLabel("Password:");
		labelPwd.setBounds(364, 38, 86, 30);
		frmXmppTools.getContentPane().add(labelPwd);
		
		txtPwd = new JTextField();
		txtPwd.setText("ximen");
		txtPwd.setColumns(10);
		txtPwd.setBounds(464, 38, 155, 30);
		frmXmppTools.getContentPane().add(txtPwd);
		
		JLabel lblHost = new JLabel("Host:");
		lblHost.setBounds(40, 81, 86, 30);
		frmXmppTools.getContentPane().add(lblHost);
		
		txtHost = new JTextField();
		txtHost.setText("172.16.122.129");
		txtHost.setColumns(10);
		txtHost.setBounds(140, 81, 155, 30);
		frmXmppTools.getContentPane().add(txtHost);
		
		JLabel lblPort = new JLabel("Port:");
		lblPort.setBounds(364, 81, 86, 30);
		frmXmppTools.getContentPane().add(lblPort);
		
		txtPort = new JTextField();
		txtPort.setText("5222");
		txtPort.setColumns(10);
		txtPort.setBounds(464, 81, 155, 30);
		frmXmppTools.getContentPane().add(txtPort);
		
		JLabel lblChat = new JLabel("Chat:");
		lblChat.setBounds(40, 233, 72, 18);
		frmXmppTools.getContentPane().add(lblChat);
		
		JScrollPane spChat = new JScrollPane();
		spChat.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
		spChat.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
		spChat.setBounds(140, 230, 577, 88);
		frmXmppTools.getContentPane().add(spChat);
		
		txtChat = new JTextArea();
		txtChat.setLineWrap(true);
		spChat.setViewportView(txtChat);
		
		JLabel lblMsg = new JLabel("Message:");
		lblMsg.setBounds(40, 321, 72, 18);
		frmXmppTools.getContentPane().add(lblMsg);
		
		spMsg = new JScrollPane();
		spMsg.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
		spMsg.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
		spMsg.setBounds(140, 331, 577, 221);
		frmXmppTools.getContentPane().add(spMsg);
		
		txtMsg = new JTextArea();
		txtMsg.setLineWrap(true);
		spMsg.setViewportView(txtMsg);
		
		JButton btnLogon = new JButton("Logon");
		btnLogon.addActionListener(new LogonAction());
		btnLogon.setBounds(789, 38, 113, 27);
		frmXmppTools.getContentPane().add(btnLogon);
		
		JButton btnLogout = new JButton("Logout");
		btnLogout.addActionListener(new LogoutAction(frmXmppTools));
		btnLogout.setBounds(789, 83, 113, 27);
		frmXmppTools.getContentPane().add(btnLogout);
		
		JButton btnSendMsg = new JButton("Send Message");
		btnSendMsg.addActionListener(new SendAction());
		btnSendMsg.setBounds(789, 122, 143, 30);
		frmXmppTools.getContentPane().add(btnSendMsg);
		
		JLabel lblTo = new JLabel("To:");
		lblTo.setBounds(40, 124, 86, 30);
		frmXmppTools.getContentPane().add(lblTo);
		
		txtTo = new JTextField();
		txtTo.setText("snowing");
		txtTo.setColumns(10);
		txtTo.setBounds(140, 124, 155, 30);
		frmXmppTools.getContentPane().add(txtTo);
		
		JLabel lblStatus = new JLabel("Status");
		lblStatus.setBounds(364, 124, 86, 30);
		frmXmppTools.getContentPane().add(lblStatus);
		
		txtStatus = new JTextField();
		txtStatus.setText("leave");
		txtStatus.setColumns(10);
		txtStatus.setBounds(464, 124, 155, 30);
		frmXmppTools.getContentPane().add(txtStatus);
		
		spMsg.setAutoscrolls(true);
		
		JButton btnClose = new JButton("Close");
		btnClose.addActionListener(new CloseAction());
		btnClose.setBounds(789, 521, 113, 27);
		frmXmppTools.getContentPane().add(btnClose);
		
		JLabel lblDomain = new JLabel("Domain:");
		lblDomain.setBounds(40, 169, 86, 30);
		frmXmppTools.getContentPane().add(lblDomain);
		
		txtDomain = new JTextField();
		txtDomain.setText("sun");
		txtDomain.setColumns(10);
		txtDomain.setBounds(140, 169, 155, 30);
		frmXmppTools.getContentPane().add(txtDomain);
		
		JButton btnClear = new JButton("Clear");
		btnClear.addActionListener(new ClearAction());
		btnClear.setBounds(789, 349, 113, 27);
		frmXmppTools.getContentPane().add(btnClear);
		
		JButton btnFin = new JButton("Fin");
		btnFin.addActionListener(new FinAction());
		btnFin.setBounds(789, 187, 113, 27);
		frmXmppTools.getContentPane().add(btnFin);
		
		JLabel lblGroup = new JLabel("Group:");
		lblGroup.setBounds(364, 169, 86, 30);
		frmXmppTools.getContentPane().add(lblGroup);
		
		txtGroup = new JTextField();
		txtGroup.setText("room1");
		txtGroup.setColumns(10);
		txtGroup.setBounds(464, 169, 155, 30);
		frmXmppTools.getContentPane().add(txtGroup);
		
		JButton btnSendGroupchat = new JButton("Send Group Message");
		btnSendGroupchat.addActionListener(new SendGroupAction());
		btnSendGroupchat.setBounds(789, 388, 143, 27);
		frmXmppTools.getContentPane().add(btnSendGroupchat);
		
		JButton btnCreateRoom = new JButton("Create Room");
		btnCreateRoom.addActionListener(new CreateRoomAction());
		btnCreateRoom.setBounds(789, 455, 143, 27);
		frmXmppTools.getContentPane().add(btnCreateRoom);
		
		JButton btnChangeNick = new JButton("Change Nick");
		btnChangeNick.addActionListener(new ChangeNickAction());
		btnChangeNick.setBounds(789, 482, 143, 27);
		frmXmppTools.getContentPane().add(btnChangeNick);
		
		JButton btnPresenceRoom = new JButton("Presence Room");
		btnPresenceRoom.addActionListener(new PresenceRoomAction());
		btnPresenceRoom.setBounds(789, 416, 143, 27);
		frmXmppTools.getContentPane().add(btnPresenceRoom);
		
		JButton button = new JButton("OM Amount");
		button.addActionListener(new OmAmountAction());
		button.setBounds(789, 268, 113, 27);
		frmXmppTools.getContentPane().add(button);
		
		JButton btnOmPage = new JButton("OM Page");
		btnOmPage.addActionListener(new OmPageAction());
		btnOmPage.setBounds(789, 291, 113, 27);
		frmXmppTools.getContentPane().add(btnOmPage);
		
		JButton btnSendMsgbody = new JButton("Quit From Room");
		btnSendMsgbody.addActionListener(new quitRoomAction());
		btnSendMsgbody.setBounds(789, 161, 143, 27);
		frmXmppTools.getContentPane().add(btnSendMsgbody);
		
		JButton btnThanksgiving = new JButton("Thanksgiving");
		btnThanksgiving.addActionListener(new ThanksgivingAction());
		btnThanksgiving.setBounds(631, 84, 143, 27);
		frmXmppTools.getContentPane().add(btnThanksgiving);
		
		JButton btnGetRoster = new JButton("Get Roster");
		btnGetRoster.addActionListener(new GetRosterAction());
		btnGetRoster.setBounds(634, 122, 143, 30);
		frmXmppTools.getContentPane().add(btnGetRoster);
		
		JButton btnPresence = new JButton("Presence");
		btnPresence.addActionListener(new PresenceAction());
		btnPresence.setBounds(789, 229, 143, 27);
		frmXmppTools.getContentPane().add(btnPresence);
		
		JButton btnRevOMPage = new JButton("Rev OM Page");
		btnRevOMPage.addActionListener(new RevOmPageAction());
		btnRevOMPage.setBounds(789, 317, 113, 27);
		frmXmppTools.getContentPane().add(btnRevOMPage);
		
		JButton btnSync = new JButton("Sync");
		btnSync.addActionListener(new SyncAction());
		btnSync.setBounds(634, 160, 143, 30);
		frmXmppTools.getContentPane().add(btnSync);
		
		JButton btnPing = new JButton("Pong");
		btnPing.addActionListener(new PongAction());
		btnPing.setBounds(631, 39, 143, 30);
		frmXmppTools.getContentPane().add(btnPing);
	}
	
	
	private void log(String str){
		
		SwingUtilities.invokeLater(new LogUpdateRunner(str));
	
		JScrollBar vertical = spMsg.getVerticalScrollBar();
		vertical.setValue( vertical.getMaximum() );	
	}
	
	class LogUpdateRunner implements Runnable{

		private String log = null;
		
		LogUpdateRunner(String log){
			this.log = log;
		}
		
		public void run() {
			txtMsg.append(new Date() + " - " + log + "\r\n");
			txtMsg.append("\r\n");	
		}		
	}
	
	
	
	class LogonAction implements ActionListener {
		public void actionPerformed(ActionEvent e) {
			// Create a connection to the jabber.org server on a specific port.
			XMPPTCPConnectionConfiguration config = null;
			
//			byte[] sxHostIP = new byte[] { (byte) 123, (byte) 56, (byte) 204, (byte) 156 };
			
			try {
				config = XMPPTCPConnectionConfiguration.builder()
						.setDebuggerEnabled(true)
						.setXmppDomain(txtDomain.getText())
						.setHostAddress(InetAddress.getByName(txtHost.getText()))
						.setPort(Integer.valueOf(txtPort.getText()).intValue())
						.setSecurityMode(XMPPTCPConnectionConfiguration.SecurityMode.disabled)
//						.setSendPresence(false)
						.addEnabledSaslMechanism(SASLMechanism.PLAIN)
//						.setResource(txtResource.getText())
						.setResource("XMPP-Tools")
//						.setSocketFactory(new DummySSLSocketFactory())
						.build();
				
				xmppCnn = new XMPPTCPConnection(config);
				xmppCnn.setUseStreamManagement(false);
				
				roster = Roster.getInstanceFor(xmppCnn);
//				roster.setRosterLoadedAtLogin(false);
				roster.setSubscriptionMode(Roster.SubscriptionMode.manual);
				
				xmppCnn.addAsyncStanzaListener(new IncomeingPacketListener(), null);
				xmppCnn.addPacketSendingListener(new OutcomingPacketInterceptor(), null);
				
				xmppCnn.connect();				
				
				xmppCnn.login(txtName.getText(), txtPwd.getText());
			} catch (Exception e1) {
				log(e1.getMessage());			
			}
			
/*			Presence presence = new Presence(Presence.Type.available);
			presence.setStatus("I am chatting");
			// Send the packet (assume we have a XMPPConnection instance called "con").
			try {
				xmppCnn.sendStanza(presence);
			} catch (Exception e1) {
				e1.printStackTrace();
				log(e1.getMessage());
			}
			*/
		}
	}
	
	
	class LogoutAction implements ActionListener {
		JFrame frame  = null;
		
		public LogoutAction(JFrame frame){
			this.frame = frame;
		}		
		
		public void actionPerformed(ActionEvent e) {
			Presence presence = new Presence(Presence.Type.unavailable);
			presence.setStatus("offline");
			
			// Send the packet (assume we have a XMPPConnection instance called "xmppCnn").			
			try {
				xmppCnn.disconnect(presence);
			} catch (Exception e1) {
				e1.printStackTrace();
				log(e1.getMessage());
			}
			
		}
	}
	
	
	class CloseAction implements ActionListener{
		public void actionPerformed(ActionEvent e) {
			frmXmppTools.dispose();
		}
	}
	
	class GetRosterAction implements ActionListener {	
		public void actionPerformed(ActionEvent e) {			
			
//			Roster roster = Roster.getInstanceFor(xmppCnn);

			try {
				roster.reload();
			} catch (Exception e1) {
				// TODO Auto-generated catch block
				e1.printStackTrace();
				log("ERR - " + e1.getMessage());
			}

//			roster.setRosterLoadedAtLogin(false);
			roster.setSubscriptionMode(Roster.SubscriptionMode.manual);

			Collection<RosterEntry> entries = roster.getEntries();
			if (entries == null || entries.isEmpty()) {
				log("------ <NO ROSTER> ------");
			} else {
				for (RosterEntry entry : entries) {
					log("<ROSTER> - " + entry.toString());
				}
			}

			roster.addRosterListener(new RosterListener() {
				public void presenceChanged(Presence presence) {
					log("Presence changed: " + presence.getFrom() + " - " + presence);
				}

				public void entriesAdded(Collection<Jid> addresses) {
					for (Jid entry : addresses) {
						log("entriesAdded - " + entry.toString());
					}
				}

				public void entriesUpdated(Collection<Jid> addresses) {
					for (Jid entry : addresses) {
						log("entriesUpdated - " + entry.toString());
					}
				}

				public void entriesDeleted(Collection<Jid> addresses) {
					for (Jid entry : addresses) {
						log("entriesDeleted - " + entry.toString());
					}
				}
			});
		}
	}
	
	class SendAction implements ActionListener {	
		public void actionPerformed(ActionEvent e) {
			Message newMessage = new Message();
			newMessage.setType(Message.Type.chat);
			newMessage.setBody(txtChat.getText());
				
//			JivePropertiesExtension extension = new JivePropertiesExtension();
//			extension.setProperty("msgMediaType", "100");
//			newMessage.addExtension(extension);
			
			try {
				newMessage.setTo(JidCreate.entityBareFrom(txtTo.getText() + "@" + txtDomain.getText()));
				newMessage.setFrom(JidCreate.entityBareFrom(txtName.getText() + "@" + txtDomain.getText()));
				
				System.out.println(newMessage.toXML());
				
				xmppCnn.sendStanza(newMessage);	
			} catch (Exception e1) {
				e1.printStackTrace();
				log(e1.getMessage());
			}
		}
	}
	
	
	class quitRoomAction implements ActionListener {	
		public void actionPerformed(ActionEvent e) {
			Message newMessage = new Message();
			newMessage.setType(Message.Type.groupchat);
			
			try {
				newMessage.setTo(JidCreate.entityBareFrom(txtGroup.getText() + "@conference." + txtDomain.getText()));
				newMessage.setFrom(JidCreate.entityBareFrom(txtName.getText() + "@" + txtDomain.getText()));
				newMessage.addExtension(new QuitRoomExtensionElement());
				
				xmppCnn.sendStanza(newMessage);	
				
			} catch (Exception e1) {
				e1.printStackTrace();
				log(e1.getMessage());
			}
		}
	}
	
	class QuitRoomExtensionElement implements ExtensionElement {

	    public static final String NAMESPACE = "sx:muc#user";
//		public static final String NAMESPACE = "fc:msg:sync";

	    public static final String ELEMENT = "quit";
		
		
		public String getElementName() {
			return ELEMENT;
		}

		public CharSequence toXML() {
			 return "<" + ELEMENT + " xmlns='" + NAMESPACE + "'/>";
		}

		public String getNamespace() {
			return NAMESPACE;
		}

	}

	
	class SendGroupAction implements ActionListener {
		
		public void actionPerformed(ActionEvent e) {
			Message newMessage = new Message();			
			newMessage.setType(Message.Type.groupchat);			
			newMessage.setBody(txtChat.getText());
			
			try {
				newMessage.setTo(JidCreate.entityBareFrom(txtGroup.getText() + "@conference." + txtDomain.getText()));
				newMessage.setFrom(JidCreate.entityBareFrom(txtName.getText() + "@" + txtDomain.getText()));

				xmppCnn.sendStanza(newMessage);
			} catch (Exception e1) {
				e1.printStackTrace();
				log(e1.getMessage());
			}
		}
	}
	
	class ThanksgivingAction implements ActionListener {
		
		public void actionPerformed(ActionEvent e) {
			Message newMessage = new Message();			
			newMessage.setType(Message.Type.groupchat);			
			newMessage.setBody(txtChat.getText());
			
			try {
				newMessage.setTo(JidCreate.entityBareFrom(txtGroup.getText() + "@conference." + txtDomain.getText()));
				newMessage.setFrom(JidCreate.entityBareFrom(txtName.getText() + "@" + txtDomain.getText()));
				
				ThanksgivingElment extension = new ThanksgivingElment();
				extension.setFrom(txtTo.getText());
				extension.setTo(txtName.getText());
				extension.setId("101");
				extension.setPortion("20");
				newMessage.addExtension(extension);

				xmppCnn.sendStanza(newMessage);
			} catch (Exception e1) {
				e1.printStackTrace();
				log(e1.getMessage());
			}
		}
	}
	
	
	class CreateRoomAction implements ActionListener {
		
		public void actionPerformed(ActionEvent e) {			
			// Create a MultiUserChat using a Connection for a room
//			MultiUserChat muc = new MultiUserChat(xmppCnn, txtGroup.getText() + "@conference." + txtDomain.getText());
//			
//			// Create the room
//			try {
//				muc.create(txtName.getText());
//				
//				// Get the the room's configuration form
//				Form form = muc.getConfigurationForm();
//				// Create a new form to submit based on the original form
//				Form submitForm = form.createAnswerForm();
//				// Add default answers to the form to submit
//				for (Iterator fields = form.getFields(); fields.hasNext();) {
//					FormField field = (FormField) fields.next();
//					if (!FormField.TYPE_HIDDEN.equals(field.getType()) && field.getVariable() != null) {
//						// Sets the default value as the answer
//						submitForm.setDefaultAnswer(field.getVariable());
//					}
//				}
//				
//				// Sets the new owner of the room
//				List owners = new ArrayList();
//				owners.add(txtName.getText() + "@" + txtDomain.getText());
//				submitForm.setAnswer("muc#roomconfig_roomowners", owners);
//				submitForm.setAnswer("muc#roomconfig_persistentroom", true);
//			//	submitForm.setAnswer("muc#roomconfig_membersonly", true);
//				submitForm.setAnswer("muc#roomconfig_allowinvites", true);
//				submitForm.setAnswer("muc#roomconfig_changesubject", true);
//				
//				// Send the completed form (with default values) to the server to
//				// configure the room
//				muc.sendConfigurationForm(submitForm);
//				
//			} catch (XMPPException e2) {
//				e2.printStackTrace();
//				log(e2.getMessage());
//			}
		}
	}
	
	class PresenceAction implements ActionListener {
		
		public void actionPerformed(ActionEvent e) {
			Presence presence = new Presence(Presence.Type.available);
			presence.setStatus("I am chatting");
			// Send the packet (assume we have a XMPPConnection instance called "con").
			try {
				xmppCnn.sendStanza(presence);
			} catch (Exception e1) {
				e1.printStackTrace();
				log(e1.getMessage());
			}
		}
	}
	
	class PresenceRoomAction implements ActionListener {
		
		public void actionPerformed(ActionEvent e) {
			// Get the MultiUserChatManager
			MultiUserChatManager manager = MultiUserChatManager.getInstanceFor(xmppCnn);

			try {
				// Create the XMPP address (JID) of the MUC.
				EntityBareJid mucJid = (EntityBareJid)JidCreate.bareFrom(txtGroup.getText() + "@conference." + txtDomain.getText());
				
				// Create a MultiUserChat using an XMPPConnection for a room
				MultiUserChat muc = manager.getMultiUserChat(mucJid);
				
				Resourcepart nickname = Resourcepart.from(txtName.getText());
				muc.join(nickname);
			}catch(Exception e1){
				e1.printStackTrace();
				log(e1.getMessage());
			}
		}
	}
	
	

	class ChangeNickAction implements ActionListener {
		
		public void actionPerformed(ActionEvent e) {
//			Connection cnn = xmppCnn;
//			
//			// Create a MultiUserChat using a Connection for a room
//			MultiUserChat muc = new MultiUserChat(cnn, txtGroup.getText() + "@conference." + txtDomain.getText());
//
//			// Create the room
//			try {
//				muc.join("s1");
//				
//				muc.changeNickname(txtChat.getText());			
//			} catch (XMPPException e2) {
//				e2.printStackTrace();
//				log(e2.getMessage());
//			}
		}
	}
	
	class FinAction implements ActionListener {	
		public void actionPerformed(ActionEvent e) {
			Fin packet = new Fin();
			packet.setVersion(Long.parseLong(txtChat.getText()));		
			log("FIN = " + packet.toXML());

			try {
				xmppCnn.sendStanza(packet);
			} catch (Exception e1) {
				e1.printStackTrace();
				log(e1.getMessage());
			}
		}
	}
	

	
	class ClearAction implements ActionListener {	
		public void actionPerformed(ActionEvent e) {
			txtMsg.setText("");
		}
	}
	
	
	class IncomeingPacketListener implements StanzaListener{		
		public void processStanza(Stanza packet) throws NotConnectedException, InterruptedException {
        	log("RCVD: " + packet.toXML());
        	
        	if(packet instanceof Message){
        		Message msg = (Message)packet;
//        		ExtensionElement elmt = msg.getExtension("receipt", "fc:msg:srv");
//        		if(elmt != null){
//                	log("ExtensionElement: " + elmt.toXML());
//        		}    		
				List<ExtensionElement> extList = msg.getExtensions();
				if (extList != null && !extList.isEmpty()) {
					for (ExtensionElement extElement : extList) {
						log("ExtensionElement: " + extElement.getElementName() + " " + extElement.getNamespace());
						log("ExtensionElement XML: " + extElement.toXML());
					}
				}
        		
        		if(msg.getType().equals(Message.Type.error)){
            		XMPPError err = msg.getError();
            		if(err != null){
            			log("ERROR CODE = " + err.getCode());
            		}       			
        		}
        		
        	}else if(packet instanceof IQ){
        		if(packet instanceof OMAmount){ 			
        			OMAmount omAmount = (OMAmount)packet;    			
        			log("OMAmount: " + packet.toXML() + "， amount = " + omAmount.getAmount());	
        		}else if(packet instanceof OfflineMessageItems){
        			OfflineMessageItems items = (OfflineMessageItems)packet;
        			log("items count = " + items.getCount());	
        			for(Message msg : items.getOfflineMessageItems()){
            			log(msg.toXML().toString());	
        			}
        		}
        	}
		}
	}
	
	
	class OutcomingPacketInterceptor implements StanzaListener{
		public void processStanza(Stanza packet) throws NotConnectedException, InterruptedException {
        	log("SEND: " + packet.toXML().toString());			
		}	
	}
	
	
	class OmAmountAction implements ActionListener {
		
		public void actionPerformed(ActionEvent e) {
			OfflineMsgAmount packet = new OfflineMsgAmount();
			
			try {
				xmppCnn.sendStanza(packet);
			} catch (Exception e1) {
				e1.printStackTrace();
				log(e1.getMessage());
			}
		}
	}
	
	
	class OmPageAction implements ActionListener {
		
		public void actionPerformed(ActionEvent e) {
			OfflineMsgPage packet = new OfflineMsgPage();
			packet.setLimit("3");
			packet.setVersion(txtChat.getText());
			
			try {
				xmppCnn.sendStanza(packet);
			} catch (Exception e1) {
				e1.printStackTrace();
				log(e1.getMessage());
			}
		}
	}
	
	class RevOmPageAction implements ActionListener {
		
		public void actionPerformed(ActionEvent e) {
			RevOfflineMsgPage packet = new RevOfflineMsgPage();
			packet.setLimit("3");
			packet.setVersion(txtChat.getText());
			
			try {
				xmppCnn.sendStanza(packet);
			} catch (Exception e1) {
				e1.printStackTrace();
				log(e1.getMessage());
			}
		}
	}
	
	
	class SyncAction implements ActionListener {
		
		public void actionPerformed(ActionEvent e) {
/*        	IQ packet = new Sync(txtChat.getText());
			
			try {
				xmppCnn.sendStanza(packet);
			} catch (Exception e1) {
				e1.printStackTrace();
				log(e1.getMessage());
			}*/
		}
	}
	
	class PongAction implements ActionListener {
		
		public void actionPerformed(ActionEvent e) {
			Ping ping;
			
			try {
				ping = new Ping(JidCreate.entityBareFrom("snowing-MBP.local@"  + txtDomain.getText()));
				
				IQ pong = ping.getPong();
				pong.setTo(txtDomain.getText());
				
				xmppCnn.sendStanza(pong);
			} catch (Exception e2) {
				e2.printStackTrace();
			}
		}
	}
}
